package main

import (

var (
	l net.Listener
)

//参数
var host = flag.String("host", "", "host")
var port = flag.String("port", "8085", "port")

func main() {
	flag.Parse()

	l, err := net.Listen("tcp", *host+":"+*port)
	if err != nil {
		log.Fatal(err)
		return
	}
	defer l.Close()
	log.Println("tcp run on " + *host + ":" + *port)

	go catchExit()

	//死循环接收数据的
	for {
		//阻塞的
		conn, err := l.Accept()
		if err != nil {
			log.Fatal(err)
		}
		log.Printf("Received message %s -> %s \n", conn.RemoteAddr(), conn.LocalAddr())
		//log.Println(conn);

		//处理数据的
		go handleRequest(conn)
	}
}

//echo 服务器
func handleRequest(conn net.Conn) {

  defer conn.Close()
  // for {
    //io.Copy(conn, conn)
    var header = make([]byte, 10)
    log.Println("start to read from conn")
    n, err := conn.Read(header)
    if err != nil {
      log.Println("conn read error:", err)
      return
    }
    log.Printf("read %d bytes, content is %s\n", n, string(header[:n]))

    size,err := strconv.ParseInt(strings.TrimSpace(string(header)),10,0)
    if err != nil{
      log.Println("error",err)
      return
    }
    var body = make([]byte,size)


    n,err = conn.Read(body)
    if err != nil{
      log.Println("conn read error:", err)
      return
    }
    log.Printf("read %d bytes, content is %s\n", n, string(body[:n]))

    body_r := strings.ToUpper(string(body))
    n,err = conn.Write([]byte(body_r))
    if err != nil{
      log.Println("conn write error:", err)
      return
    }
    log.Printf("write %d bytes, content is %s\n", n, string(body_r[:n]))

    start := time.Now().Unix()
    ticker := time.NewTicker(time.Second * time.Duration(1))
    for{
            select {
            case <-ticker.C:
              now := time.Now().Unix()
              if now - start > 3{
                break
              }
              log.Println(now)
              conn.Write([]byte(strconv.FormatInt(now,10)))
            }
    }
  // }

}

//安全退出的
func catchExit() {
	sigTerm := syscall.Signal(15)
	sig := make(chan os.Signal)
	signal.Notify(sig, os.Interrupt, sigTerm)

	for {
		switch <-sig {
		case os.Interrupt, sigTerm:
			if l != nil {
				l.Close()
			}
			//l.Close()
			log.Println("ready to exit")
			os.Exit(0)
		}
	}
}
